﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DidaManager.Native.Network
{
    public class DeviceSearchUdpServer
    {
        private const int MAX_BROADCAST_COUNT = 5;
        private const int BROADCAST_TIMEOUT_MS = 5000;
        private const int BROADCAST_PORT = 8888; // 默认广播端口
        private const int LISTEN_PORT = 8889;    // 默认监听端口

        private readonly ConcurrentDictionary<string, DeviceInfo> _discoveredDevices;
        private UdpClient? _udpClient;
        private bool _isSearching;

        public DeviceSearchUdpServer()
        {
            _discoveredDevices = new ConcurrentDictionary<string, DeviceInfo>();
        }

        /// <summary>
        /// 开始搜索设备
        /// </summary>
        /// <param name="broadcastMessage">广播消息内容</param>
        /// <param name="broadcastPort">广播端口</param>
        /// <param name="listenPort">监听端口</param>
        /// <returns>发现的设备列表</returns>
        public async Task<List<DeviceInfo>> SearchDevicesAsync(string broadcastMessage, int broadcastPort = BROADCAST_PORT, int listenPort = LISTEN_PORT)
        {
            if (_isSearching)
            {
                throw new InvalidOperationException("设备搜索正在进行中，请等待完成后再试");
            }

            _isSearching = true;
            _discoveredDevices.Clear();

            try
            {
                // 创建UDP客户端用于监听响应
                _udpClient = new UdpClient(listenPort);
                _udpClient.EnableBroadcast = true;

                // 启动监听任务
                var listenTask = StartListeningAsync();

                // 执行广播
                await PerformBroadcastAsync(broadcastMessage, broadcastPort);

                // 等待监听任务完成或超时
                await Task.WhenAny(listenTask, Task.Delay(BROADCAST_TIMEOUT_MS));

                return _discoveredDevices.Values.ToList();
            }
            finally
            {
                _isSearching = false;
                _udpClient?.Close();
                _udpClient?.Dispose();
                _udpClient = null;
            }
        }

        /// <summary>
        /// 执行广播
        /// </summary>
        private async Task PerformBroadcastAsync(string message, int port)
        {
            using var broadcastClient = new UdpClient();
            broadcastClient.EnableBroadcast = true;

            var messageBytes = Encoding.UTF8.GetBytes(message);
            var broadcastEndPoint = new IPEndPoint(IPAddress.Broadcast, port);

            for (int i = 0; i < MAX_BROADCAST_COUNT; i++)
            {
                try
                {
                    await broadcastClient.SendAsync(messageBytes, messageBytes.Length, broadcastEndPoint);
                    Console.WriteLine($"第 {i + 1} 次广播发送成功");
                    
                    // 每次广播间隔500ms
                    if (i < MAX_BROADCAST_COUNT - 1)
                    {
                        await Task.Delay(500);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"第 {i + 1} 次广播发送失败: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 开始监听设备响应
        /// </summary>
        private async Task StartListeningAsync()
        {
            if (_udpClient == null) return;

            var endTime = DateTime.Now.AddMilliseconds(BROADCAST_TIMEOUT_MS);

            while (DateTime.Now < endTime && _isSearching)
            {
                try
                {
                    var result = await _udpClient.ReceiveAsync();
                    var responseMessage = Encoding.UTF8.GetString(result.Buffer);
                    var deviceEndPoint = result.RemoteEndPoint;

                    // 处理设备响应
                    ProcessDeviceResponse(responseMessage, deviceEndPoint);
                }
                catch (ObjectDisposedException)
                {
                    // UDP客户端已被释放，停止监听
                    break;
                }
                catch (SocketException ex)
                {
                    Console.WriteLine($"接收数据时发生错误: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 处理设备响应，过滤重复设备
        /// </summary>
        private void ProcessDeviceResponse(string responseMessage, IPEndPoint deviceEndPoint)
        {
            try
            {
                var deviceInfo = ParseDeviceResponse(responseMessage, deviceEndPoint);
                if (deviceInfo != null)
                {
                    // 使用IP地址作为唯一标识符来过滤重复设备
                    var deviceKey = deviceInfo.IpAddress;
                    
                    if (_discoveredDevices.TryAdd(deviceKey, deviceInfo))
                    {
                        Console.WriteLine($"发现新设备: {deviceInfo.Name} ({deviceInfo.IpAddress})");
                    }
                    else
                    {
                        Console.WriteLine($"过滤重复设备: {deviceInfo.Name} ({deviceInfo.IpAddress})");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"解析设备响应时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 解析设备响应消息
        /// </summary>
        private DeviceInfo? ParseDeviceResponse(string responseMessage, IPEndPoint deviceEndPoint)
        {
            // 这里可以根据实际的响应格式进行解析
            // 响应格式为 {IP:"127.0.0.1",MAC:"1654"}
            var jObject = JObject.Parse(responseMessage);
            var ip = jObject["IP"]?.ToString();
            var mac = jObject["MAC"]?.ToString();
            
            if (string.IsNullOrEmpty(ip) || string.IsNullOrEmpty(mac))
            {
                return null;
            }

            return new DeviceInfo
            {
                MacAddress = mac,
                IpAddress = ip,
            };
        }

        /// <summary>
        /// 停止设备搜索
        /// </summary>
        public void StopSearch()
        {
            _isSearching = false;
            _udpClient?.Close();
        }

        /// <summary>
        /// 获取已发现的设备列表
        /// </summary>
        public List<DeviceInfo> GetDiscoveredDevices()
        {
            return _discoveredDevices.Values.ToList();
        }

        /// <summary>
        /// 清除已发现的设备
        /// </summary>
        public void ClearDiscoveredDevices()
        {
            _discoveredDevices.Clear();
        }
    }

    /// <summary>
    /// 设备信息类
    /// </summary>
    public class DeviceInfo
    {
        public string Name { get; set; } = "";
        public string DeviceType { get; set; } = "";
        public string MacAddress { get; set; } = "";
        public string IpAddress { get; set; } = "";
        public int Port { get; set; }
        public DateTime LastSeen { get; set; }
        public string RawResponse { get; set; } = "";
    }
}
